/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
 *
 */

import { FileSet, TaskInputValue } from '@ohos/hvigor';
import fse from 'fs-extra';
import path from 'path';

import { BuildArtifactConst } from '../const/build-directory-const.js';
import { CommonConst, ValidateRegExp } from '../const/common-const.js';
import { ModuleType } from '../enum/module-type-enum.js';
import { ModuleModel } from '../model/module/module-model.js';
import { ModuleJson } from '../options/configure/module-json-options.js';
import { RouterMapOptions } from '../options/configure/router-map-options.js';
import { Dependency } from '../project/dependency/core/dependency-interface.js';
import { DependencyManager } from '../project/dependency/dependency-manager.js';
import { FileUtil } from '../utils/file-util.js';
import { getJson5Obj } from '../utils/json-util.js';
import { OhosLogger } from '../utils/log/ohos-logger.js';
import { generateOhmUrlForSourceFile } from '../utils/ohmurl-utils.js';

import { TaskNames } from './common/task-names.js';
import { TargetTaskService } from './service/target-task-service.js';
import { OhosHapTask } from './task/ohos-hap-task.js';
import RouterMapObj = RouterMapOptions.RouterMapObj;
import ModuleOptObj = ModuleJson.ModuleOptObj;
import intermediatesRouterMapObj = RouterMapOptions.intermediatesRouterMapObj;
import { findDuplicateElement, getIntersection } from '../utils/array-util.js';
import { CoreModuleModelImpl } from '../model/module/core-module-model-impl.js';
import { HarTargetUtil } from '../utils/har-target-util.js';
import { getLocalDependencyRouterMap } from '../utils/dependency-util.js';

export class ProcessRouterMap extends OhosHapTask {
  protected _log: OhosLogger = OhosLogger.getLogger(ProcessRouterMap.name);
  private readonly compileEntry: string[];
  private readonly routerMapFileName: string | undefined;
  private readonly intermediatesRouterMapObjs: intermediatesRouterMapObj[];
  private readonly intermediatesTempRouterMapFilePath: string;
  private readonly intermediatesToLoaderRouterMap: string;

  private readonly useNormalizedOHMUrl: boolean;
  private moduleName2Target: Map<string, string> = new Map();

  constructor(targetService: TargetTaskService) {
    super(targetService, TaskNames.Task.PROCESS_ROUTER_MAP);
    this.compileEntry = [];
    this.routerMapFileName = this.targetService.getRouterMapJsonFileName(this.moduleModel);
    this.intermediatesRouterMapObjs = [];
    this.intermediatesTempRouterMapFilePath = this.pathInfo.getIntermediatesRouterMap(this.routerMapFileName ?? BuildArtifactConst.TEMP_ROUTER_MAP_FILE_NAME);
    this.intermediatesToLoaderRouterMap = this.pathInfo.getIntermediatesRouterMap(BuildArtifactConst.LOADER_ROUTER_MAP_FILE_NAME);
    this.useNormalizedOHMUrl = !!this.targetService.getBuildOption()?.strictMode?.useNormalizedOHMUrl;
  }

  declareInputFiles(): FileSet {
    const fileSet = super.declareInputFiles();
    const isOhpmProject = this.projectModel.isOhpmProject();
    fileSet
      .addEntry(isOhpmProject ? this.moduleModel.getOhPackageJson5Path() : this.moduleModel.getPackageJsonPath())
      .addEntry(isOhpmProject ? this.projectModel.getOhPackageJson5Path() : this.projectModel.getPackageJsonPath())
      .addEntry(this.moduleModel.getJsonPathByTargetName(this.targetName));
    const routerMapJsonPath = this.targetService.getRouterMapJsonPath(this.moduleModel);
    if (routerMapJsonPath && fse.existsSync(routerMapJsonPath)) {
      fileSet.addEntry(routerMapJsonPath);
    }
    if (fse.existsSync(this.pathInfo.getIntermediatesPkgContextInfoPath())) {
      fileSet.addEntry(this.pathInfo.getIntermediatesPkgContextInfoPath());
    }
    return fileSet;
  }

  declareOutputFiles(): FileSet {
    return super.declareOutputFiles().addEntry(this.intermediatesTempRouterMapFilePath).addEntry(this.intermediatesToLoaderRouterMap);
  }

  declareInputs(): Map<string, TaskInputValue> {
    const map = super.declareInputs();
    map.set(CommonConst.USE_NORMALIZED_OHM_URL, this.useNormalizedOHMUrl);
    map.set('obfuscated', this.targetService.isOpenSource());
    map.set('byteCodeHar', this.targetService.isByteCodeHar());
    this.service.getHarDependencies().forEach((dependency) => {
      if (dependency.isLocal()) {
        const localDependencyRouterMapObjList = this.getLocalDependencyRouterMap(dependency);
        if (localDependencyRouterMapObjList) {
          map.set('localDependencyRouterMapObjList', JSON.stringify(localDependencyRouterMapObjList));
        }
      } else {
        const remoteDependencyRouterMapObjList = DependencyManager.getRemoteDependencyRouterMapObjList(dependency);
        if (remoteDependencyRouterMapObjList) {
          map.set('remoteDependencyRouterMapObjList', JSON.stringify(remoteDependencyRouterMapObjList));
        }
      }
    });
    return map;
  }

  async beforeAlwaysAction(): Promise<void> {
    await super.beforeAlwaysAction();
    this.moduleName2Target = HarTargetUtil.calDepHarTargets(this.targetService);
  }

  protected doTaskAction(): void {
    const moduleRouterMapObjList = this.targetService.getTargetRouterMapObjList(this.moduleModel);
    const moduleType = this.service.getModuleModel().getModuleType();
    if (moduleType === ModuleType.Har && !this.targetService.isBundledDependencies()) {
      // 处理har包routerMap配置
      this.processHarRouterMap(moduleRouterMapObjList);
    } else {
      // 处理hap/hsp包routerMap配置
      this.processHapOrHspRouterMap(moduleRouterMapObjList);
    }
  }

  /**
   * 处理har模块的routerMap
   * @param harRouterMapObjList
   * @private
   */
  private processHarRouterMap(harRouterMapObjList: RouterMapObj[] | undefined): void {
    if (!harRouterMapObjList) {
      return;
    }

    this.checkModuleRouterMapObj(harRouterMapObjList, this.moduleModel, false);
    this.checkRouterMapObjName(harRouterMapObjList);
    const hasUseTsHarFileSuffix = this.hasUseTsHarField() ? '.ts' : '.js';
    harRouterMapObjList.forEach((routerMapObj: RouterMapObj) => {
      const intermediateRouterMapObj: intermediatesRouterMapObj = {
        name: routerMapObj.name,
        pageSourceFile: path.resolve(this.module.getNodeDir(), routerMapObj.pageSourceFile),
        buildFunction: routerMapObj.buildFunction,
      };
      this.intermediatesRouterMapObjs.push(intermediateRouterMapObj);
      this.compileEntry.push(intermediateRouterMapObj.pageSourceFile);

      if (!this.targetService.isOpenSource() || this.targetService.isByteCodeHar()) {
        // 闭源har需修改pageSourceFile为ets/ts后缀的为js
        const pageSourceFile = routerMapObj.pageSourceFile;
        const fileSuffix = FileUtil.getFileSuffix(pageSourceFile);
        if (ValidateRegExp.DYNAMIC_IMPORT_FILE_SUFFIX_REG_EXP.test(fileSuffix)) {
          Object.assign(routerMapObj, {
            pageSourceFile: `${pageSourceFile.substring(0, pageSourceFile.lastIndexOf('.'))}${hasUseTsHarFileSuffix}`,
            originalSuffix: `.${fileSuffix}`,
          });
        }
      }
    });

    this.generateTempRouterMap(harRouterMapObjList, this.intermediatesRouterMapObjs);
  }

  /**
   * 处理entry/feature/hsp模块的routerMap
   * @param hapOrHspRouterMapObjList
   * @private
   */
  private processHapOrHspRouterMap(hapOrHspRouterMapObjList: RouterMapObj[] | undefined): void {
    const allRouterMapObjList: RouterMapObj[] = [];

    // 处理当前模块自有的routerMap配置
    this.processModuleSelfRouterMap(allRouterMapObjList, hapOrHspRouterMapObjList);

    // 处理当前模块依赖的har/hsp依赖的routerMap配置
    this.processModuleDependencyRouterMap(allRouterMapObjList);

    // 校验合并后的routerMapList对象名唯一
    this.checkRouterMapObjName(allRouterMapObjList);

    this.generateTempRouterMap(allRouterMapObjList, this.intermediatesRouterMapObjs);
  }

  /**
   * 处理模块自有routerMap
   * @param allRouterMapObjList
   * @param moduleSelfRouterMapObjList
   * @private
   */
  private processModuleSelfRouterMap(allRouterMapObjList: RouterMapObj[], moduleSelfRouterMapObjList: RouterMapObj[] | undefined): void {
    if (!moduleSelfRouterMapObjList) {
      return;
    }

    this.checkModuleRouterMapObj(moduleSelfRouterMapObjList, this.moduleModel, false);
    moduleSelfRouterMapObjList.forEach((moduleRouterMapObj: RouterMapObj) => {
      const modulePageSourceFile = path.resolve(this.moduleModel.getModule().getNodeDir(), moduleRouterMapObj.pageSourceFile);
      this.compileEntry.push(modulePageSourceFile);

      let ohmurl = '';
      if (this.useNormalizedOHMUrl) {
        const pkgContextInfoPath = this.pathInfo.getIntermediatesPkgContextInfoPath();

        // 获取语义信息表
        const pkgContextInfos = getJson5Obj(pkgContextInfoPath);
        const pkgContextInfo = pkgContextInfos[this.packageJsonObj.name];
        ohmurl = generateOhmUrlForSourceFile(pkgContextInfo, moduleRouterMapObj.pageSourceFile);
      } else {
        ohmurl = this.generateModuleOhmurl(this.moduleName, moduleRouterMapObj.pageSourceFile);
      }

      // 写入hap/hsp自身ohmurl,bundleName,moduleName信息
      Object.assign(moduleRouterMapObj, {
        ohmurl: ohmurl,
        bundleName: this.getBundleName(),
        moduleName: this.moduleName,
      });

      const intermediateRouterMapObj: intermediatesRouterMapObj = {
        ohmurl,
        name: moduleRouterMapObj.name,
        pageSourceFile: modulePageSourceFile,
        buildFunction: moduleRouterMapObj.buildFunction,
      };
      this.intermediatesRouterMapObjs.push(intermediateRouterMapObj);
    });

    allRouterMapObjList.push(...moduleSelfRouterMapObjList);
  }

  /**
   * 处理模块依赖的routerMap
   * @param allRouterMapObjList
   * @private
   */
  private processModuleDependencyRouterMap(allRouterMapObjList: RouterMapObj[]): void {
    // 处理当前模块直接,间接依赖的包routerMap配置
    // Map<ModuleModel, RouterMapObj[]>用于收集依赖模块和其对应的routerMapObj集合 处理同一模块被不同名称依赖场景
    const moduleFlag2RouterMapObjList: Map<ModuleModel, RouterMapObj[]> = new Map<ModuleModel, RouterMapOptions.RouterMapObj[]>();
    this.service.getHarDependencies().forEach((dependency) => {
      if (dependency.isLocal()) {
        // 处理本地依赖的routerMap
        this.processLocalDependencyRouterMap(dependency, allRouterMapObjList, moduleFlag2RouterMapObjList);
      } else {
        // 处理远程依赖的routerMap
        this.processRemoteDependencyRouterMap(dependency, allRouterMapObjList);
      }
    });
  }

  private getLocalDependencyRouterMap (dependency: Dependency) {
    return getLocalDependencyRouterMap(this.projectModel, this.targetService, dependency);
  }

  /**
   * 处理模块本地依赖的routerMap
   * @param localDependency 模块直接依赖/间接依赖
   * @param allRouterMapObjList
   * @param moduleFlag2RouterMapObjList
   * @private
   */
  private processLocalDependencyRouterMap(
    localDependency: Dependency,
    allRouterMapObjList: RouterMapObj[],
    moduleFlag2RouterMapObjList: Map<ModuleModel, RouterMapObj[]>
  ): void {
    const localDependencyModuleModel = DependencyManager.getModuleModelByDependency(localDependency, this.projectModel);
    const localDependencyRouterMapObjList = this.getLocalDependencyRouterMap(localDependency);
    if (!localDependencyModuleModel || !localDependencyRouterMapObjList || moduleFlag2RouterMapObjList.has(localDependencyModuleModel)) {
      return;
    }

    moduleFlag2RouterMapObjList.set(localDependencyModuleModel, localDependencyRouterMapObjList);
    this.checkModuleRouterMapObj(localDependencyRouterMapObjList, localDependencyModuleModel as CoreModuleModelImpl, true);
    localDependencyRouterMapObjList.forEach((dependencyRouterMapObj: RouterMapObj) => {
      const modulePageSourceFile = path.resolve(localDependency.getDependencyRootPath(), dependencyRouterMapObj.pageSourceFile);
      const localDependencyModuleType = localDependencyModuleModel.getModuleType();
      this.pushCompileEntry(localDependencyModuleType, modulePageSourceFile);

      // 写入hap/hsp依赖本地har/hsp依赖中存在routerMap时的ohmurl,bundleName,moduleName信息
      let ohmurl = '';
      if (this.useNormalizedOHMUrl) {
        ohmurl = this.getOhmUrlWithNormalize(localDependency, dependencyRouterMapObj.pageSourceFile);
      } else {
        if (localDependencyModuleType === ModuleType.Shared) {
          ohmurl = this.generateModuleOhmurl(localDependencyModuleModel.getName(), dependencyRouterMapObj.pageSourceFile);
        }
        if (localDependencyModuleType === ModuleType.Har) {
          ohmurl = this.generateHarOhmurl(this.moduleName, localDependencyModuleModel.getName(), dependencyRouterMapObj.pageSourceFile, true);
        }
      }
      Object.assign(dependencyRouterMapObj, {
        ohmurl: ohmurl,
        bundleName: this.getBundleName(),
        moduleName: this.moduleName,
      });

      const intermediateRouterMapObj: intermediatesRouterMapObj = {
        ohmurl,
        name: dependencyRouterMapObj.name,
        pageSourceFile: modulePageSourceFile,
        buildFunction: dependencyRouterMapObj.buildFunction,
      };
      this.routerMapAddPackageName(dependencyRouterMapObj, localDependency);
      this.intermediatesRouterMapObjs.push(intermediateRouterMapObj);
    });

    this.checkDependencyRouterMap(localDependency, localDependencyRouterMapObjList);
    allRouterMapObjList.push(...localDependencyRouterMapObjList);
  }

  /**
   * 处理模块远程依赖的routerMap(对比本地依赖,远程依赖在打包上传时已回填pageModule字段,所以一定存在pageModule)
   * 模块远程依赖无需校验路由表配置 上传远程仓时已确保路由表配置正确
   * @param remoteDependency
   * @param allRouterMapObjList
   * @private
   */
  private processRemoteDependencyRouterMap(remoteDependency: Dependency, allRouterMapObjList: RouterMapObj[]): void {
    const remoteDependencyRouterMapObjList = DependencyManager.getRemoteDependencyRouterMapObjList(remoteDependency);
    if (!remoteDependencyRouterMapObjList) {
      return;
    }

    const moduleJsonObj: ModuleOptObj = DependencyManager.getModuleObjByRemoteDependency(remoteDependency);
    const moduleType = moduleJsonObj.module.type;
    remoteDependencyRouterMapObjList.forEach((remoteRouterMapObj: RouterMapObj) => {
      const pageSourceFile = remoteRouterMapObj.pageSourceFile;
      const modulePageSourceFile = path.resolve(remoteDependency.getDependencyRootPath(), pageSourceFile);

      // 字节码har的router_map中的pageSource不用写进compileEntry
      if (!remoteDependency.isByteCodeHarDependency()) {
        this.pushCompileEntry(moduleType, modulePageSourceFile);
      }

      // 写入hap/hsp依赖远程har/hsp依赖存在routerMap时的ohmurl,bundleName,moduleName信息
      const remoteDependencyModuleName = moduleJsonObj.module.name;
      let ohmurl;
      if (this.useNormalizedOHMUrl) {
        ohmurl = this.getOhmUrlWithNormalize(remoteDependency, remoteRouterMapObj.pageSourceFile);
      } else {
        if (moduleType === ModuleType.Shared) {
          ohmurl = this.generateModuleOhmurl(remoteDependencyModuleName, remoteRouterMapObj.pageSourceFile);
        }
        if (moduleType === ModuleType.Har) {
          ohmurl = this.generateHarOhmurl(this.moduleName, remoteDependencyModuleName, modulePageSourceFile, false, remoteDependency.getDependencyName());
        }
      }
      Object.assign(remoteRouterMapObj, {
        ohmurl: remoteDependency.isBundleDependency() ? remoteRouterMapObj.ohmurl ?? ohmurl : ohmurl,
        bundleName: this.getBundleName(),
        moduleName: this.moduleName,
      });

      const intermediateRouterMapObj: intermediatesRouterMapObj = {
        ohmurl,
        name: remoteRouterMapObj.name,
        pageSourceFile: modulePageSourceFile,
        buildFunction: remoteRouterMapObj.buildFunction,
      };
      this.routerMapAddPackageName(remoteRouterMapObj, remoteDependency);
      this.intermediatesRouterMapObjs.push(intermediateRouterMapObj);
    });

    this.checkDependencyRouterMap(remoteDependency, remoteDependencyRouterMapObjList);
    allRouterMapObjList.push(...remoteDependencyRouterMapObjList);
  }

  /**
   * bundleHAR依赖的源码har在temp_router_map.json中新加入一个packageName字段标识属于哪个模块
   * @param dependencyRouterMapObj
   * @param dependency
   * @private
   */
  private routerMapAddPackageName(dependencyRouterMapObj: RouterMapObj, dependency: Dependency) {
    dependencyRouterMapObj.packageName = dependencyRouterMapObj.packageName || dependency.getPackageName();
  }

  /**
   * 校验本模块routerMap对象配置
   * @param routerMapObjList
   * @param moduleModel
   * @param isDependency
   * @private
   */
  private checkModuleRouterMapObj(routerMapObjList: RouterMapObj[] | undefined, moduleModel: CoreModuleModelImpl, isDependency: boolean): void {
    if (!routerMapObjList) {
      return;
    }

    const moduleName = moduleModel.getName();
    routerMapObjList.forEach((routerMapObj: RouterMapObj) => {
      const routerMapJsonPath = isDependency
        ? DependencyManager.getDependencyModuleRouterMapJsonPath(moduleModel, this.moduleName2Target.get(moduleName))
        : this.targetService.getRouterMapJsonPath(moduleModel);
      const modulePageSourceFile = this.getModulePageSourceFile(moduleModel, routerMapObj);
      if (routerMapObj.pageSourceFile === '' || modulePageSourceFile === '' || !modulePageSourceFile || !fse.existsSync(modulePageSourceFile)) {
        // pageModule对应的pageSourceFile配置的代码文件路径必须要真实存在
        this._log.printErrorExit('PAGE_SOURCE_FILE_NOT_FOUND', [modulePageSourceFile ?? '', moduleName, routerMapJsonPath], [[moduleName]]);
      }

      if (!ValidateRegExp.PAGE_SOURCE_FILE_REG_EXP.test(routerMapObj.pageSourceFile)) {
        this._log.printErrorExit('PAGE_SOURCE_FILE_FORMAT_INVALID',[moduleName, routerMapJsonPath]);
      }
    });
  }

  /**
   * 获取模块pageSourceFile
   * @param moduleModel
   * @param routerMapObj
   * @private
   */
  private getModulePageSourceFile(moduleModel: ModuleModel, routerMapObj: RouterMapObj): string | undefined {
    const pageSourceFile = routerMapObj.pageSourceFile;
    if (pageSourceFile === '') {
      return undefined;
    }

    return path.resolve(moduleModel.getModule().getNodeDir(), pageSourceFile);
  }

  /**
   * 校验直接/间接依赖的routerMap配置
   * @param dependency
   * @param routerMapObjList
   * @private
   */
  private checkDependencyRouterMap(dependency: Dependency, routerMapObjList: RouterMapObj[] | undefined): void {
    if (!routerMapObjList) {
      return;
    }

    routerMapObjList.forEach((routerMapObj: RouterMapObj) => {
      const moduleModelByDependency = DependencyManager.getModuleModelByDependency(dependency, this.projectModel);
      if (!moduleModelByDependency) {
        return;
      }
      const dependencyModuleName = moduleModelByDependency?.getName();
      const dependencyRouterMapJsonPath = DependencyManager.getDependencyModuleRouterMapJsonPath(moduleModelByDependency, this.moduleName2Target.get(dependencyModuleName));
      const pageSourceFile = routerMapObj.pageSourceFile;
      const modulePageSourceFile = path.resolve(dependency.getDependencyRootPath(), pageSourceFile);

      if (pageSourceFile === '' || modulePageSourceFile === '' || !modulePageSourceFile || !fse.existsSync(modulePageSourceFile)) {
        // pageModule对应的pageSourceFile配置的代码文件路径必须要真实存在
        this._log.printErrorExit(
          'PAGE_SOURCE_FILE_NOT_FOUND',
          [pageSourceFile === '' ? '' : modulePageSourceFile, dependencyModuleName, dependencyRouterMapJsonPath ?? ''],
          [[dependencyModuleName]],
        );
      }
    });
  }

  /**
   * 校验routerMap集合中对象名称唯一
   * @param routerMapObjList
   * @private
   */
  private checkRouterMapObjName(routerMapObjList: RouterMapObj[] | undefined): void {
    if (!routerMapObjList || routerMapObjList.length <= 1) {
      return;
    }

    // 收集当前模块及其依赖模块名与其routerMap的配置对象名数组的键值对 moduleName:[routerMapObjName1...]
    const module2RouterMapName = new Map<string, string[]>();
    routerMapObjList.forEach((routerMapObj) => {
      const packageName: string = routerMapObj.packageName as string;
      if (module2RouterMapName.has(packageName)) {
        const routerMapObjNameArr = module2RouterMapName.get(packageName);
        if (!routerMapObjNameArr) {
          return;
        }
        if (!routerMapObjNameArr.includes(routerMapObj.name)) {
          routerMapObjNameArr.push(routerMapObj.name);
          module2RouterMapName.set(packageName, routerMapObjNameArr);
        }
      } else {
        module2RouterMapName.set(packageName, [routerMapObj.name]);
      }
    });

    // 校验是否存在重复 用上述相同格式保存用于日志打印
    const errorMap = new Map<string, string[]>();
    module2RouterMapName.forEach((eachRouterMapObjNameArr, eachModuleName) => {
      // 当前模块存在重复name的routerMap配置
      const duplicateRouterMapObjNameArr = findDuplicateElement(eachRouterMapObjNameArr);

      // 当前模块与其他依赖模块存在重复name的routerMap配置
      module2RouterMapName.forEach((otherRouterMapObjNameArr, otherModuleName) => {
        if (otherModuleName === eachModuleName) {
          return;
        }
        const otherDuplicateRouterMapObjNameArr = getIntersection(otherRouterMapObjNameArr, eachRouterMapObjNameArr);
        if (otherDuplicateRouterMapObjNameArr.length !== 0) {
          duplicateRouterMapObjNameArr.push(...otherDuplicateRouterMapObjNameArr);
        }
      });

      if (duplicateRouterMapObjNameArr.length !== 0) {
        errorMap.set(eachModuleName, Array.from(new Set<string>(duplicateRouterMapObjNameArr)));
      }
    });
    if (errorMap.size !== 0) {
      this._log.printErrorExit('DUPLICATE_ROUTERMAP_OBJECT_NAME_DETECTED', undefined, [[JSON.stringify(Object.fromEntries(errorMap.entries()))]]);
    }
  }

  /**
   * 获取当前工程bundleName
   * @private
   */
  private getBundleName(): string {
    return this.targetData.getProduct().bundleName ?? this.projectModel.getDefaultBundleName();
  }

  /**
   * 生成entry/feature/hsp模块ohmurl
   * @param moduleName
   * @param pageSourceFile
   * @private
   */
  private generateModuleOhmurl(moduleName: string, pageSourceFile: string): string {
    const pageSourceFileWithoutSuffix = pageSourceFile.substring(0, pageSourceFile.indexOf('.'));
    const newPageSourceFile = pageSourceFileWithoutSuffix.includes('src/main/ets/')
      ? pageSourceFileWithoutSuffix.replace('src/main/', '')
      : pageSourceFileWithoutSuffix;
    return `@bundle:${this.getBundleName()}/${moduleName}/${newPageSourceFile}`;
  }

  /**
   * 生成本地/远程har模块ohmurl
   * @param hostModuleName
   * @param moduleName
   * @param pageSourceFile
   * @param isLocalDependency
   * @param remoteDependencyName
   * @private
   */
  private generateHarOhmurl(
    hostModuleName: string,
    moduleName: string,
    pageSourceFile: string,
    isLocalDependency: boolean,
    remoteDependencyName?: string,
  ): string {
    if (isLocalDependency) {
      const pageSourceFileWithoutSuffix = pageSourceFile.substring(0, pageSourceFile.indexOf('.'));
      const newPageSourceFile = pageSourceFileWithoutSuffix.includes('src/main/ets/')
        ? pageSourceFileWithoutSuffix.replace('src/main/', '')
        : pageSourceFileWithoutSuffix;
      return `@bundle:${this.getBundleName()}/${hostModuleName}@${moduleName}/${newPageSourceFile}`;
    }

    // 去除文件后缀
    const fileNameWithoutSuffix = path.parse(pageSourceFile).name;
    const pageSourceFileWithoutFileSuffix = `${pageSourceFile.substring(0, pageSourceFile.lastIndexOf(path.sep) + 1)}${fileNameWithoutSuffix}`;

    // 截取第一个oh_modules并替换其为pkg_modules
    const replaceFirstOhModules = pageSourceFileWithoutFileSuffix
      .substring(pageSourceFileWithoutFileSuffix.indexOf(CommonConst.OH_MODULES))
      .replace(CommonConst.OH_MODULES, CommonConst.PKG_MODULES);

    // 找到远程依赖模块名之前的第一个oh_modules并替换其为pkg_modules
    const depNameIndex = replaceFirstOhModules.indexOf(path.sep + remoteDependencyName?.replace('/', path.sep) + path.sep);
    const beforeDepNameStr = replaceFirstOhModules.substring(0, depNameIndex);
    const replaceBeforeDepNameOhModuleStr = beforeDepNameStr.replace(path.basename(beforeDepNameStr), CommonConst.PKG_MODULES);
    const reconnectStr = replaceBeforeDepNameOhModuleStr + replaceFirstOhModules.substring(depNameIndex);
    const sepPattern = new RegExp('\\' + path.sep, 'g');
    return `@package:${reconnectStr.replace(sepPattern, '/')}`;
  }

  /**
   * hsp不用将pageSourceFile写入compileEntry
   * @param moduleType
   * @param pageSourceFile
   * @private
   */
  private pushCompileEntry(moduleType: string, pageSourceFile: string): void {
    if (moduleType === ModuleType.Shared) {
      return;
    }

    this.compileEntry.push(pageSourceFile);
  }

  initTaskDepends(): void {
    //
  }

  /**
   * 获取新规格化的ohmUrl
   *
   * @param localDependency
   * @param pageSourceFile
   * @private
   */
  private getOhmUrlWithNormalize(localDependency: Dependency, pageSourceFile: string) {
    const pkgName = localDependency.getPackageName();
    const pkgContextInfoPath = this.pathInfo.getIntermediatesPkgContextInfoPath();

    // 获取语义信息表
    const pkgContextInfos = getJson5Obj(pkgContextInfoPath);
    if (!pkgContextInfos) {
      this._log.printErrorExit('PKG_CONTEXT_INFO_PATH_NOT_AVAILABLE', [pkgContextInfoPath]);
    }
    const pkgContextInfo = pkgContextInfos[pkgName];
    if (!pkgContextInfo) {
      this._log.printErrorExit('PKG_NAME_NOT_EXIST', [pkgName, pkgContextInfoPath]);
    }
    return generateOhmUrlForSourceFile(pkgContextInfo, pageSourceFile);
  }

  /**
   * 将处理过后的routerMap配置集合保存在中间产物临时目录中
   * @param routerMapObjList
   * @param intermediatesTempRouterMapObjList
   * @private
   */
  private generateTempRouterMap(routerMapObjList: RouterMapObj[] | undefined, intermediatesTempRouterMapObjList: intermediatesRouterMapObj[] | undefined) {
    fse.ensureFileSync(this.intermediatesTempRouterMapFilePath);
    fse.writeFileSync(this.intermediatesTempRouterMapFilePath, JSON.stringify({ routerMap: routerMapObjList }));

    fse.ensureFileSync(this.intermediatesToLoaderRouterMap);
    fse.writeFileSync(this.intermediatesToLoaderRouterMap, JSON.stringify({ routerMap: intermediatesTempRouterMapObjList }));
  }
}
